package com.pan.kang.role.impl;

import com.pan.kang.dao.IAccComprehensiveQueryDao;
import com.pan.kang.role.IAccComprehensiveQueryRole;
import com.pan.kang.util.AccConditionUtils;
import com.pan.kang.util.ConvertUtil;
import com.pan.kang.util.DBUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class AccComprehensiveQueryRole implements IAccComprehensiveQueryRole {

    @Autowired
    private IAccComprehensiveQueryDao comprehensiveQueryDao;

    public Map<String, Object> findList(Map<String, Object> param, Map<String, Object> pageCondition) {
        Map<String, Object> resultMap = new HashMap<>();
        Boolean export = ConvertUtil.toBoolean(param.get("export"));
        String findSql = "";
        Map<String, Object> findMap = this.findListByPro(param);
        findSql = ConvertUtil.toString(findMap.get("findSql"));
        String whereCondition;
        if (export) {
            Map<String, String> exportSql = new HashMap();
            findSql = (String)exportSql.get("sqlKey");
            resultMap.put("findSql", findSql);
            param.put("isAllData", "1");
            resultMap.put("keyValue", exportSql.get("qtDimVouDtlKeyValue"));
            resultMap.put("dimFieNams", exportSql.get("dimFieNams"));
        } else if (param.get("returnCount") != null && ConvertUtil.toInt(param.get("returnCount")) > 0) {
            int whereLastIndex = findSql.lastIndexOf("WHERE");
            whereCondition = findSql.substring(whereLastIndex);
            if (!DBUtil.isMySql() && !whereCondition.contains("ROWNUM")) {
                findSql = "SELECT * FROM (" + findSql + " ) WHERE ROWNUM<= " + ConvertUtil.toInt(param.get("returnCount"));
            } else if (!whereCondition.contains("LIMIT")) {
                findSql = findSql + " LIMIT " + ConvertUtil.toInt(param.get("returnCount"));
            }
        }

        Integer returnCount = (Integer) (param.get("returnCount"));
        whereCondition = ConvertUtil.toString(param.get("accbookid"));
        resultMap.put("findSql", findSql);
        List<Map> queryResults = comprehensiveQueryDao.findResultTableListBySql(findSql, param);
        String selectPftCompId = ConvertUtil.toString(param.get("selectPftCompId"));
        if (StringUtils.isNotEmpty(selectPftCompId)) {
            String fiscYea = ConvertUtil.toString(param.get("accountYear"));
            this.reBuildResults(queryResults, fiscYea, whereCondition);
        }

        resultMap.put("queryResults", queryResults);
        if (param.get("isAllData") != null && !CollectionUtils.isEmpty(queryResults)) {
            resultMap.put("isAllData", ConvertUtil.toInt(param.get("isAllData")));
        } else if (queryResults.size() >= returnCount) {
            resultMap.put("isAllData", 0);
        } else {
            resultMap.put("isAllData", 1);
        }
        resultMap.put("pageCondition", pageCondition);
        return resultMap;
    }


    private void reBuildResults(List<Map> queryResults, String fiscYea, String accBook) {
    }


    private Map<String, Object> findListByPro(Map<String, Object> queryParam) {
        Map<String, Object> returnMap = new HashMap();
        String findSql = "";
        long s = System.currentTimeMillis();
        String accountYear = ConvertUtil.toString(queryParam.get("accountYear"));
        String accBookid = ConvertUtil.toString(queryParam.get("accbookid"));
        String dateStatus = ConvertUtil.toString(queryParam.get("dateStatus"));
        this.putBeginBalanceParam(queryParam, "detailCompid", queryParam.get("detailCompid"));
        Integer mxdwQuery = (Integer)queryParam.get("mxdwQuery");
        String selectCompids = (String)AccConditionUtils.isAllMatch(new Boolean[]{mxdwQuery != null && mxdwQuery == 1}).handleConditionWithReturn(() -> {
            return ConvertUtil.toString(queryParam.get("detailCompid"));
        }, () -> {
            return ConvertUtil.toString(queryParam.get("selectcompid"));
        });
        String queryModel = ConvertUtil.toString(queryParam.get("queryModel"));
        int returnCount = ConvertUtil.toInt(queryParam.get("QUERY_MAX_RET_COUNT_OJB"));
        if (returnCount == -1) {
            returnCount = 1000;
        }
        int hzDataLimit = ConvertUtil.toInt(queryParam.get("HZ_DATA_LIMIT_QUERY"));
        queryParam.put("hzDataLimit", hzDataLimit);
        this.putBeginBalanceParam(queryParam, "hzDataLimit", hzDataLimit);
        String validComp = selectCompids.split(",")[0];
        boolean isBottomUnit;
        String compid;
        if (queryParam.get("returnCount") != null && ConvertUtil.toInt(queryParam.get("returnCount")) <= returnCount) {
            if (ConvertUtil.toInt(queryParam.get("returnCount")) == 0) {
                compid = selectCompids.split(",")[0];
                isBottomUnit = false;
                queryParam.put("ytFilterCompid", compid);
                this.putBeginBalanceParam(queryParam, "ytFilterCompid", compid);
                String unitControl = "1500";
                queryParam.put("unitControl", unitControl);
                queryParam.put("isExport", 1);
                this.putBeginBalanceParam(queryParam, "unitControl", unitControl);
                this.putBeginBalanceParam(queryParam, "isExport", 1);
                if (mxdwQuery != 1) {
                    Integer keyValue = 0;
                    returnMap.put("keyValue", keyValue);
                } else {
                    returnMap.put("keyValue", 0);
                }
            } else {
                isBottomUnit = false;
                queryParam.put("ytFilterCompid", selectCompids);
                compid = "1500";
                queryParam.put("unitControl", compid);
                queryParam.put("isExport", 0);
                this.putBeginBalanceParam(queryParam, "ytFilterCompid", selectCompids);
                this.putBeginBalanceParam(queryParam, "unitControl", compid);
                this.putBeginBalanceParam(queryParam, "isExport", 0);
            }
        } else {
            queryParam.put("returnCount", returnCount);
            this.putBeginBalanceParam(queryParam, "returnCount", returnCount);
            compid = "1500";
            isBottomUnit = false;
            queryParam.put("unitControl", compid);
            this.putBeginBalanceParam(queryParam, "unitControl", compid);
            queryParam.put("isExport", 1);
            this.putBeginBalanceParam(queryParam, "isExport", 1);
        }

        queryParam.put("isBottomUnit", isBottomUnit);
        this.putBeginBalanceParam(queryParam, "isBottomUnit", isBottomUnit);
        String findTwoSql = comprehensiveQueryDao.buildDwKmInfoHzTempTablePro(queryParam);
        findSql =  comprehensiveQueryDao.bulidDwHzResultTable(findTwoSql, queryParam);
        findSql = setQcQmFx(queryParam, findSql, false);
        returnMap.put("findSql", findSql);
        return returnMap;
    }

    private void putBeginBalanceParam(Map<String, Object> queryParam, String key, Object value) {
        Map<String, Object> beginBalanceParam = (Map)queryParam.get("beginBalanceParam");
        if (!Objects.isNull(beginBalanceParam) && !beginBalanceParam.isEmpty()) {
            beginBalanceParam.put(key, value);
        }

    }

    public static String setQcQmFx(Map<String, Object> param, String findSql, Boolean isExport) {
        int isDirectionColVal = ConvertUtil.toInt(param.get("isDirectionColVal"));
        if (isDirectionColVal != 1) {
            return findSql;
        } else {
            int isForCur = ConvertUtil.toInt(param.get("isForCur"));
            Map<String, Object> beginBalanceParam = (Map)param.get("beginBalanceParam");
            boolean isNcYeQuery = Objects.nonNull(beginBalanceParam) && !beginBalanceParam.isEmpty();
            findSql = findSql.toUpperCase();
            String[] valArray = new String[]{"QCFX,", "QCYE_BWB,", "QMFX,", "QMYE_BWB,", "QCYE,", "QMYE,", "QCYE_SL,", "QMYE_SL,", "QCYE_DJ,", "QMYE_DJ,", "QCFX,", "QCYE_BWB_YJZ ,", "QMFX,", "QMYE_BWB_YJZ ,", "QCYE_YJZ ,", "QMYE_YJZ ,", "QCFX_NC,", "QCYE_NC,", "QCYE_BWB_NC,"};
            String[] valArray2 = new String[]{"QCFX", "QCYE_BWB", "QMFX", "QMYE_BWB", "QCYE", "QMYE", "QCYE_SL", "QMYE_SL", "QCYE_DJ", "QMYE_DJ", "QCFX", "QCYE_BWB_YJZ", "QMFX", "QMYE_BWB_YJZ", "QCYE_YJZ", "QMYE_YJZ", "QCFX_NC", "QCYE_NC", "QCYE_BWB_NC"};
            String crStr = "'借'";
            String drStr = "'贷'";
            Object zero = 0;
            if (isExport) {
                crStr = "'借'";
                drStr = "'贷'";
                zero = "'0'";
            }

            for(int i = 0; i < valArray.length; ++i) {
                int index = findSql.indexOf(valArray[i]);
                if (index != -1) {
                    String value = findSql.substring(0, index);
                    if (value.trim().lastIndexOf(")") == value.trim().length() - 1) {
                        value = getSubstringStr(value);
                    } else {
                        int lastIndexOf = value.lastIndexOf(",");
                        if (value.lastIndexOf(",") != -1) {
                            value = value.substring(lastIndexOf + 1);
                            if (StringUtils.isBlank(value)) {
                                value = valArray[i].substring(0, valArray[i].length() - 1);
                            }
                        }
                    }

                    if (StringUtils.isNotBlank(value.trim())) {
                        valArray[i] = value;
                    }
                } else {
                    valArray[i] = valArray2[i];
                }
            }

            String result = " QCFX,CASE WHEN " + valArray[0] + " = " + crStr + " THEN " + valArray[1] + " ELSE 0 END AS QCYE_BWB_J, \nCASE WHEN " + valArray[0] + " = " + drStr + " THEN " + valArray[1] + " ELSE 0 END AS QCYE_BWB_D, \nCASE WHEN " + valArray[2] + " = " + crStr + " THEN " + valArray[3] + " ELSE 0 END AS QMYE_BWB_J, \nCASE WHEN " + valArray[2] + " = " + drStr + " THEN " + valArray[3] + " ELSE 0 END AS QMYE_BWB_D \n";
            if (isNcYeQuery) {
                if (isForCur == 1) {
                    result = " QCFX,CASE WHEN " + valArray[0] + " = " + crStr + " THEN " + valArray[1] + " ELSE 0 END AS QCYE_BWB_J, \n CASE WHEN " + valArray[0] + " = " + drStr + " THEN " + valArray[1] + " ELSE 0 END AS QCYE_BWB_D, \n CASE WHEN " + valArray[16] + " = " + crStr + " THEN " + valArray[18] + " ELSE " + zero + " END AS QCYE_BWB_NC_J, \n CASE WHEN " + valArray[16] + " = " + drStr + " THEN " + valArray[18] + " ELSE " + zero + " END AS QCYE_BWB_NC_D, \n CASE WHEN " + valArray[16] + " = " + crStr + " THEN " + valArray[17] + " ELSE " + zero + " END AS QCYE_NC_J, \n CASE WHEN " + valArray[16] + " = " + drStr + " THEN " + valArray[17] + " ELSE " + zero + " END AS QCYE_NC_D, \n CASE WHEN " + valArray[2] + " = " + crStr + " THEN " + valArray[3] + " ELSE 0 END AS QMYE_BWB_J, \n CASE WHEN " + valArray[2] + " = " + drStr + " THEN " + valArray[3] + " ELSE 0 END AS QMYE_BWB_D  \n";
                } else {
                    result = " QCFX,CASE WHEN " + valArray[0] + " = " + crStr + " THEN " + valArray[1] + " ELSE 0 END AS QCYE_BWB_J, \n CASE WHEN " + valArray[0] + " = " + drStr + " THEN " + valArray[1] + " ELSE 0 END AS QCYE_BWB_D, \n CASE WHEN " + valArray[16] + " = " + crStr + " THEN " + valArray[18] + " ELSE " + zero + " END AS QCYE_BWB_NC_J, \n CASE WHEN " + valArray[16] + " = " + drStr + " THEN " + valArray[18] + " ELSE " + zero + " END AS QCYE_BWB_NC_D, \n CASE WHEN " + valArray[2] + " = " + crStr + " THEN " + valArray[3] + " ELSE 0 END AS QMYE_BWB_J, \n CASE WHEN " + valArray[2] + " = " + drStr + " THEN " + valArray[3] + " ELSE 0 END AS QMYE_BWB_D  \n";
                }
            }

            if (findSql.contains("QCYE,")) {
                result = result + ",CASE WHEN " + valArray[0] + " = " + crStr + " THEN " + valArray[4] + " ELSE 0 END AS QCYE_J, \nCASE WHEN " + valArray[0] + " = " + drStr + " THEN " + valArray[4] + " ELSE 0 END AS QCYE_D, \nCASE WHEN " + valArray[2] + " = " + crStr + " THEN " + valArray[5] + " ELSE 0 END AS QMYE_J, \nCASE WHEN " + valArray[2] + " = " + drStr + " THEN " + valArray[5] + " ELSE 0 END AS QMYE_D \n";
            }

            if (findSql.contains("QCYE_SL,")) {
                result = result + ",CASE WHEN " + valArray[0] + " = " + crStr + " THEN " + valArray[6] + " ELSE " + zero + " END AS QCSL_J, \nCASE WHEN " + valArray[0] + " = " + drStr + " THEN " + valArray[6] + " ELSE " + zero + " END AS QCSL_D, \nCASE WHEN " + valArray[2] + " = " + crStr + " THEN " + valArray[7] + " ELSE " + zero + " END AS QMSL_J, \nCASE WHEN " + valArray[2] + " = " + drStr + " THEN " + valArray[7] + " ELSE " + zero + " END AS QMSL_D, \nCASE WHEN " + valArray[0] + " = " + crStr + " THEN " + valArray[8] + " ELSE " + zero + " END AS QCDJ_J, \nCASE WHEN " + valArray[0] + " = " + drStr + " THEN " + valArray[8] + " ELSE " + zero + " END AS QCDJ_D, \nCASE WHEN " + valArray[2] + " = " + crStr + " THEN " + valArray[9] + " ELSE " + zero + " END AS QMDJ_J, \nCASE WHEN " + valArray[2] + " = " + drStr + " THEN " + valArray[9] + " ELSE " + zero + " END AS QMDJ_D \n";
            }

            if (findSql.contains("QCYE_BWB_YJZ")) {
                result = result + ",CASE WHEN " + valArray[10] + " = " + crStr + " THEN " + valArray[11] + " ELSE " + zero + " END AS QCYE_BWB_YJZ_J, \nCASE WHEN " + valArray[10] + " = " + drStr + " THEN " + valArray[11] + " ELSE " + zero + " END AS QCYE_BWB_YJZ_D, \nCASE WHEN " + valArray[12] + " = " + crStr + " THEN " + valArray[13] + " ELSE " + zero + " END AS QMYE_BWB_YJZ_J, \nCASE WHEN " + valArray[12] + " = " + drStr + " THEN " + valArray[13] + " ELSE " + zero + " END AS QMYE_BWB_YJZ_D \n";
            }

            if (findSql.contains("QCYE_YJZ")) {
                result = result + ",CASE WHEN " + valArray[10] + " = " + crStr + " THEN " + valArray[14] + " ELSE " + zero + " END AS QCYE_YJZ_J, \nCASE WHEN " + valArray[10] + " = " + drStr + " THEN " + valArray[14] + " ELSE " + zero + " END AS QCYE_YJZ_D, \nCASE WHEN " + valArray[12] + " = " + crStr + " THEN " + valArray[15] + " ELSE " + zero + " END AS QMYE_YJZ_J, \nCASE WHEN " + valArray[12] + " = " + drStr + " THEN " + valArray[15] + " ELSE " + zero + " END AS QMYE_YJZ_D \n";
            }

            findSql = findSql.replaceFirst("\\bQCFX\\b", result);
            return findSql;
        }
    }

    public static String getSubstringStr(String str) {
        String rightStr = str.substring(str.lastIndexOf("("));
        Integer rightCount = StringUtils.countMatches(rightStr, ")");
        String subStr = "(";
        String result = "";
        int count = 0;

        int index;
        for(index = str.length(); count < rightCount && (index = str.lastIndexOf(subStr, index - 1)) != -1; ++count) {
        }

        if (count == rightCount) {
            result = str.substring(str.substring(0, index).lastIndexOf(",") + 1);
        }

        return result;
    }
}
